package com.ayu.shortlink.engine.service.handler.remind;

import com.ayu.shortlink.engine.common.constant.RedisCacheConstant;
import com.ayu.shortlink.engine.common.enums.CouponRemindTypeEnum;
import com.ayu.shortlink.engine.dao.entity.CouponTemplateRemindDO;
import com.ayu.shortlink.engine.dao.mapper.CouponTemplateRemindMapper;
import com.ayu.shortlink.engine.mq.basics.event.CouponRemindEvent;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 处理提醒信息 (利用线程池)
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class ExecuteCouponRemindHandler {
    private final CouponTemplateRemindMapper couponTemplateRemindMapper;
    private final StringRedisTemplate stringRedisTemplate;
    private final Integer CouponRemindType = CouponRemindTypeEnum.values().length;
    private final Integer BIT_SITE = 12;
    //线程池
    private final ExecutorService executorService = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),
            Runtime.getRuntime().availableProcessors()<<1,
            60,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(10000),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );


    public void handler(CouponRemindEvent event){
        executorService.execute(() -> {
            String longStr = stringRedisTemplate.opsForValue()
                    .get(String.format(RedisCacheConstant.COUPON_REMIND_INFORMATION, event.getUser_id()));
            Long information = null;
            if (longStr != null) {
                information = Long.parseLong(longStr);
            }
            if (information != null){
                LambdaQueryWrapper<CouponTemplateRemindDO> queryWrapper = Wrappers.lambdaQuery(CouponTemplateRemindDO.class)
                        .eq(CouponTemplateRemindDO::getShopNumber, event.getShopNumber())
                        .eq(CouponTemplateRemindDO::getUserId, event.getUser_id())
                        .eq(CouponTemplateRemindDO::getCouponTemplateId, event.getCouponTemplateId());

                CouponTemplateRemindDO remindDO = couponTemplateRemindMapper.selectOne(queryWrapper);

                // 无提示信息
                if(remindDO == null){
                    return;
                }

                information = remindDO.getInformation();
                // 放入Redis 设置过期时间1小时即可
                stringRedisTemplate.opsForValue()
                        .set(String.format(RedisCacheConstant.COUPON_REMIND_INFORMATION, event.getUser_id()),
                                String.valueOf(remindDO.getInformation()),
                                1,
                                TimeUnit.HOURS);
            }

            //进行提示
            doRemind(information,event.getLevel());
        });
    }

    /**
     * 进行用户提醒
     */
    private void doRemind(Long information, Integer level) {
        for (int i = 0; i < CouponRemindType; i++) {
            Long var = 1L << i*BIT_SITE + level;
            if((information & var) != 0){
                String describeByType = CouponRemindTypeEnum.getDescribeByType(i);
                log.info("正在以{}提醒用户",describeByType);
            }
        }
    }
}
